// 用户仓库
import { defineStore } from 'pinia'
import { reqLogin, reqLogout, reqUserInfo } from '@/api/user'
import type { loginForm, loginReponse, UserInfoResponse } from '@/api/user/type'
import type { UserState } from '../types'
// token的添加和获取
import { GET_TOKEN, REMOVE_TOKEN, SET_TOKEN } from '@/utils/token'
// 引入路由（进行路由匹配和权限设置）
import { constantRoute, asyncRoute, anyRoute } from '@/router/route'
import router from '@/router'
// 引入深拷贝方法
//@ts-ignore
import cloneDeep from 'lodash/cloneDeep'
// 引入路由对象的ts类型
import {  RouteRecordName, RouteRecordRaw } from "vue-router";

// 组合式API
let useUserStore = defineStore('User', {
  // 数据
  state: (): UserState => {
    return {
      // 用户唯一标识
      token: GET_TOKEN(),
      // 菜单的路由数组
      menuRoute: constantRoute,
      // 用户名
      username: '',
      // 用户头像（后端提供的用户头像连接无法访问，故先用现成的）
      avatar: '/src/assets/images/avatar.png',
      // 用户需要的异步路由
      userAsyncRoute: [],
      // 用户的按钮权限列表
      buttons: []
    }
  },
  // 处理逻辑 | 异步
  actions: {
    // 登录
    async userLogin(data: loginForm) {
      let result: loginReponse = await reqLogin(data)
      // 登录成功
      if (result.code == 200) {
        this.token = result.data
        // // 本地持久化存储token
        SET_TOKEN(result.data)
        return 'login success'
      }
      // 登录失败
      else {
        let msg = result.data
        if (msg == null) msg = '账号不存在'
        return Promise.reject(new Error(msg))
      }
    },
    // 获取用户信息
    async userInfo() {
      // 发送请求，获取用户信息
      let result: UserInfoResponse = await reqUserInfo()
      // 获取成功
      if (result.code == 200) {
        this.username = result.data.name
        // 后台返回的头像数据无法正常访问
        // this.avatar = result.data.avatar
        this.buttons = result.data.buttons;

        // 计算当前用户需要展示的异步路由的数据(传输深拷贝的异步路由，防止对原路由发生修改)
        this.userAsyncRoute = filterAsyncRoute(
          cloneDeep(asyncRoute),
          result.data.routes,
        )
        this.menuRoute = [...constantRoute, ...this.userAsyncRoute, ...anyRoute]
        // 在路由器中追加设置路由
        this.userAsyncRoute.concat(anyRoute).forEach((route: any) => {
          router.addRoute(route)
        })
        // 打印用户的全部路由
        // console.log(this.username, router.getRoutes());

        return 'getUserInfo success'
      } else {
        return Promise.reject(new Error(result.message))
      }
    },
    // 退出登录
    async userLogout() {
      // 通知服务器token失效
      let result = await reqLogout()
      if (result.code == 200) {
        // 清空仓库的用户数据
        this.token = ''
        this.username = ''
        this.avatar = ''
        REMOVE_TOKEN()
        // 退出时，移除异步路由（防止登录其他账号时，路由设置遗留）
        this.userAsyncRoute.forEach((route: RouteRecordRaw) => {
          router.removeRoute(route.name as RouteRecordName)
        })
        return 'logout success'
      } else {
        return Promise.reject(new Error(result.message))
      }
    },
  },
  // 计算
  getters: {},
})

// 过滤用户需要展示的异步路由
function filterAsyncRoute(asyncRoute: any, routes: any) {
  // 对异步路由进行过滤
  return asyncRoute.filter((item: any) => {
    // 用户需要的路由中包含异步路由
    if (routes.includes(item.name)) {
      // 对异步路由的子路由进行过滤
      if (item.children && item.children.length > 0)
        item.children = filterAsyncRoute(item.children, routes)
      return true
    }
  })
}

export default useUserStore
